package ca.scotthyndman.as2haxe.dom;

import java.util.ArrayList;
import java.util.List;

import ca.scotthyndman.as2haxe.dom.visitor.IVisitor;

/**
 * Represents the package specification in a type definition. This has been
 * introduced to provide a link to the package as a whole, but still exist as a
 * child in an AST.
 * 
 * @author Scott Hyndman
 */
public class ASPackageDeclaration extends ASTNode {

	/* --- Property definitions --- */

	/**
	 * The "name" structural property of this node type.
	 */
	public static final ASChildPropertyDescriptor NAME_PROPERTY = new ASChildPropertyDescriptor(
			ASPackageDeclaration.class, "name", ASName.class, true);

	/* --- Members --- */

	/** The package name */
	private ASName name;

	/* --- Construction --- */

	/**
	 * Constructs a new package
	 */
	public ASPackageDeclaration(AST ast) {
		super(ast);
	}

	/* --- Properties --- */

	/**
	 * Returns the package's name.
	 */
	public ASName getName() {
		return name;
	}

	/**
	 * Sets the package's name.
	 * 
	 * @param name
	 */
	public void setName(ASName name) {
		if (name == null) {
			throw new IllegalArgumentException();
		}

		ASTNode oldChild = this.name;
		preReplaceChild(oldChild, name, NAME_PROPERTY);
		this.name = name;
		postReplaceChild(oldChild, name, NAME_PROPERTY);
	}

	/* --- Internal getters/setters --- */

	/*
	 * (omit javadoc for this method) Method declared on ASTNode.
	 */
	final ASTNode internalGetSetChildProperty(
			ASChildPropertyDescriptor property, boolean get, ASTNode child) {
		if (property == NAME_PROPERTY) {
			if (get) {
				return getName();
			} else {
				setName((ASName) child);
				return null;
			}
		}

		// allow default implementation to flag the error
		return super.internalGetSetChildProperty(property, get, child);
	}

	/* --- Visitor --- */

	public void accept(IVisitor as2Visitor, boolean recursive) {
		recursive = as2Visitor.visit(this) && recursive;
		if (recursive) {

		}
	}

	/* --- Properties --- */

	/**
	 * A list of property descriptors (element type:
	 * {@link ASPropertyDescriptor}), or null if uninitialized.
	 */
	private static final List<ASPropertyDescriptor> PROPERTY_DESCRIPTORS;

	static {
		List<Object> propertyList = new ArrayList<Object>(2);
		createPropertyList(ASPackageDeclaration.class, propertyList);
		addProperty(NAME_PROPERTY, propertyList);
		PROPERTY_DESCRIPTORS = reapPropertyList(propertyList);
	}

	/**
	 * Returns a list of structural property descriptors for this node type.
	 * Clients must not modify the result.
	 * 
	 * @return a list of property descriptors (element type:
	 *         {@link ASPropertyDescriptor})
	 */
	public static List<ASPropertyDescriptor> propertyDescriptors() {
		return PROPERTY_DESCRIPTORS;
	}
}
